#include "inc/zg291global.h"
#include "ui_zg291global.h"
#include <QtDebug>
#include <QThread>
ZG291GLOBAL::ZG291GLOBAL(QSerialPort *serialPort,QTimer *m_timer,QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ZG291GLOBAL),
    serialPort(serialPort),
    m_timer(m_timer)
{
    ui->setupUi(this);
}

ZG291GLOBAL::~ZG291GLOBAL()
{
    delete ui;
}

void ZG291GLOBAL::on_pushButton_clicked()
{
    if (!serialPort || !serialPort->isOpen()) {
        qDebug() << "Serial port not ready!";
        return;
    }

    // Clear any buffered data
    serialPort->clear();

    // First request: read 3 registers starting from 0x0000
    QByteArray request1;
    request1.append(static_cast<char>(0x00));    // Slave address
    request1.append(static_cast<char>(0x03));    // Function code
    request1.append(static_cast<char>(0x00));    // Start address high
    request1.append(static_cast<char>(0x00));    // Start address low
    request1.append(static_cast<char>(0x00));    // Register count high
    request1.append(static_cast<char>(0x03));    // Register count low (3 registers)

    quint16 crc1 = calculateCRC(request1);
    request1.append(static_cast<char>(crc1 & 0xFF));
    request1.append(static_cast<char>((crc1 >> 8) & 0xFF));

    // Send first request
    if (serialPort->write(request1) == -1) {
        qDebug() << "First write failed:" << serialPort->errorString();
        return;
    }

    if (!serialPort->waitForBytesWritten(1000)) {
        qDebug() << "First write timeout";
        return;
    }

    // Wait for first response
    if (!serialPort->waitForReadyRead(1000)) {
        qDebug() << "First read timeout!";
        return;
    }

    QByteArray response1 = serialPort->readAll();
    while (serialPort->waitForReadyRead(100)) {
        response1 += serialPort->readAll();
    }

    // Parse first response
    if(response1.size() >= 9) {
        quint16 slave_add = (static_cast<quint8>(response1[3]) << 8) | static_cast<quint8>(response1[4]);
        ui->slave_add->setText(QString::number(slave_add));

        quint16 slave_buadrate = (static_cast<quint8>(response1[5]) << 8) | static_cast<quint8>(response1[6]);
        ui->slave_baudrate->setCurrentIndex(slave_buadrate);

        quint16 device_state = (static_cast<quint8>(response1[7]) << 8) | static_cast<quint8>(response1[8]);
        ui->device_state->setCurrentIndex(device_state);
    } else {
        qDebug() << "Invalid first response length:" << response1.size();
        return;
    }

    // Add small delay between requests (100ms)
    QThread::msleep(100);
    serialPort->clear();

    // Second request: read 1 register at address 0x007F
    QByteArray request2;
    request2.append(static_cast<char>(0x00));    // Slave address
    request2.append(static_cast<char>(0x03));    // Function code
    request2.append(static_cast<char>(0x00));    // Start address high
    request2.append(static_cast<char>(0x7F));    // Start address low
    request2.append(static_cast<char>(0x00));    // Register count high
    request2.append(static_cast<char>(0x01));    // Register count low (1 register)

    quint16 crc2 = calculateCRC(request2);
    request2.append(static_cast<char>(crc2 & 0xFF));
    request2.append(static_cast<char>((crc2 >> 8) & 0xFF));

    // Send second request
    if (serialPort->write(request2) == -1) {
        qDebug() << "Second write failed:" << serialPort->errorString();
        return;
    }

    if (!serialPort->waitForBytesWritten(1000)) {
        qDebug() << "Second write timeout";
        return;
    }

    // Wait for second response
    if (!serialPort->waitForReadyRead(1000)) {
        qDebug() << "Second read timeout!";
        return;
    }

    QByteArray response2 = serialPort->readAll();
    while (serialPort->waitForReadyRead(100)) {
        response2 += serialPort->readAll();
    }

    // Parse second response
    if(response2.size() >= 5) {
        quint16 register7F_value = (static_cast<quint8>(response2[3]) << 8) | static_cast<quint8>(response2[4]);
        qDebug() << "Register 0x7F value:" << register7F_value;
        // Update your UI element here
        ui->net_hz->setText(QString::number(register7F_value));
    } else {
        qDebug() << "Invalid second response length:" << response2.size();
    }
}


void ZG291GLOBAL::on_pushButton_2_clicked()
{
    if (!serialPort || !serialPort->isOpen()) {
        qDebug() << "Serial port not ready!";
        return;
    }

    // Clear any buffered data
    serialPort->clear();

    // First write: write 3 registers starting from 0x0000
    QByteArray request1;
    request1.append(static_cast<char>(0x00));    // Slave address
    request1.append(static_cast<char>(0x10));    // Function code (Preset Multiple Registers)
    request1.append(static_cast<char>(0x00));    // Start address high
    request1.append(static_cast<char>(0x00));    // Start address low
    request1.append(static_cast<char>(0x00));    // Register count high
    request1.append(static_cast<char>(0x03));    // Register count low (3 registers)
    request1.append(static_cast<char>(0x06));    // Byte count (3 registers * 2 bytes each)

    // Get values from UI for first write
    quint16 slave_add = ui->slave_add->text().toUShort();
    request1.append(static_cast<char>((slave_add >> 8) & 0xFF));
    request1.append(static_cast<char>(slave_add & 0xFF));

    quint16 slave_baudrate = ui->slave_baudrate->currentIndex();
    request1.append(static_cast<char>((slave_baudrate >> 8) & 0xFF));
    request1.append(static_cast<char>(slave_baudrate & 0xFF));

    quint16 device_state = ui->device_state->currentIndex();
    request1.append(static_cast<char>((device_state >> 8) & 0xFF));
    request1.append(static_cast<char>(device_state & 0xFF));

    // Calculate CRC for first request
    quint16 crc1 = calculateCRC(request1);
    request1.append(static_cast<char>(crc1 & 0xFF));
    request1.append(static_cast<char>((crc1 >> 8) & 0xFF));

    // Send first write request
    if (serialPort->write(request1) == -1) {
        qDebug() << "First write failed:" << serialPort->errorString();
        return;
    }

    if (!serialPort->waitForBytesWritten(1000)) {
        qDebug() << "First write timeout";
        return;
    }

    // Wait for first response
    if (!serialPort->waitForReadyRead(1000)) {
        qDebug() << "First response timeout!";
        return;
    }

    QByteArray response1 = serialPort->readAll();
    while (serialPort->waitForReadyRead(100)) {
        response1 += serialPort->readAll();
    }

    // Check first response (should be 8 bytes)
    if(response1.size() < 8) {
        qDebug() << "Invalid first response length:" << response1.size();
        return;
    }

    // Add small delay between requests (100ms)
    QThread::msleep(100);
    serialPort->clear();

    // Second write: write 1 register at address 0x007F
    QByteArray request2;
    request2.append(static_cast<char>(0x00));    // Slave address
    request2.append(static_cast<char>(0x06));    // Function code (Preset Single Register)
    request2.append(static_cast<char>(0x00));    // Register address high
    request2.append(static_cast<char>(0x7F));    // Register address low

    // Get value from UI for second write
    quint16 net_hz = ui->net_hz->text().toUShort();
    request2.append(static_cast<char>((net_hz >> 8) & 0xFF));
    request2.append(static_cast<char>(net_hz & 0xFF));

    // Calculate CRC for second request
    quint16 crc2 = calculateCRC(request2);
    request2.append(static_cast<char>(crc2 & 0xFF));
    request2.append(static_cast<char>((crc2 >> 8) & 0xFF));

    // Send second write request
    if (serialPort->write(request2) == -1) {
        qDebug() << "Second write failed:" << serialPort->errorString();
        return;
    }

    if (!serialPort->waitForBytesWritten(1000)) {
        qDebug() << "Second write timeout";
        return;
    }

    // Wait for second response
    if (!serialPort->waitForReadyRead(1000)) {
        qDebug() << "Second response timeout!";
        return;
    }

    QByteArray response2 = serialPort->readAll();
    while (serialPort->waitForReadyRead(100)) {
        response2 += serialPort->readAll();
    }

    // Check second response (should be 8 bytes)
    if(response2.size() < 8) {
        qDebug() << "Invalid second response length:" << response2.size();
    } else {
        qDebug() << "Both writes successful";
    }
}
